<pre>
    <script>

        class XRegExp {
            constructor(source, flag, root = "root") {
                this.table = new Map()
                this.regExp = new RegExp(this.compileRegExp(source, root, 0).source, flag)
                console.log(this.regExp)
                //console.log(this.table)
            }

            compileRegExp(source, name, start) {
                if (source[name] instanceof RegExp)
                    return {
                        source: source[name].source,
                        length: 0
                    }

                let length = 0


                let regExp = source[name].replace(/\<([^>]+)\>/g, (str, $1) => {
                    this.table.set(start + length, $1)
                    this.table.set($1, start + length)
                    ++length
                    let r = this.compileRegExp(source, $1,start + length)
                    length += r.length
                    return "(" + r.source + ")"
                })
                return { source: regExp, length: length }
            }
            exec(string) { 
                let r = this.regExp.exec(string)
                for(let i = 1; i < r.length; i++){
                    if(r[i] !== void 0){
                        console.log(this.table.get(i-1))
                    }
                }
                console.log(r[0])
                return r
            }

            get lastIndex() { 
                return this.regExp.lastIndex
            }

            set lastIndex(value) { 
                return this.regExp.lastIndex = value
            }


        }


        function scan(str) {
            //let regExp = / |\n|<comments>|<token>/
            let regExp = new XRegExp({
                InputElement: "<WhiteSpace>|<LineTerminator>|<Comments>|<Token>",
                WhiteSpace: / /,
                LineTerminator: /\n/,
                Comments: /\/\*(?:[^*]|\*[^\/])*\*\//,
                Token: "<Literal>|<Keywords>|<Identifer>|<Punctuator>",
                Literal: "<NumericLiteral>|<BooleanLiteral>|<StringLiteral>|<NullLiteral>",
                NumericLiteral: /(?:[1-9][0-9]*|0)(?:\.[0-9]*)?|\.[0-9]+/,
                BooleanLiteral: /true|false/,
                StringLiteral: /\"(?:[^"\n]|\\[\s\S])*\"|\'(?:[^'\n]|\\[\s\S])*\'/,
                NullLiteral: /null/,
                Identifer: /[a-zA-Z_$][a-zA-Z0-9_$]*/,
                Keywords: /if|else|for|fuction|let/,
                Punctuator: /\(|=>|=|\<|\+\+|==|\)|\*|\.|\{|\}|\[|\]|;|:/

            },"g" ,"InputElement")
            while (regExp.lastIndex < str.length) {
                let r = regExp.exec(str)
                document.write(r[0])
                if (!r[0].length)
                    break

            }
        }

        scan(`http.createServer((request, response) => {
            let body = [];
            request.on('error', (err) => {
                console.error(err);
            }).on('data',(chunk) => {
                body.push(chunk.toString());
            }).on('end',()=>{
                body = Buffer.concat([Buffer.from(body.toString())]).toString();
                console.log("body:",body);
                response.writeHead(200,{'Content-Type':'text/html'});
                response.end('hellw world\n');
            })
        }).listen(8088);`)


        /*
        http.createServer((request, response) => {
            let body = [];
            request.on('error', (err) => {
                console.error(err);
            }).on('data',(chunk) => {
                body.push(chunk.toString());
            }).on('end',()=>{
                body = Buffer.concat([Buffer.from(body.toString())]).toString();
                console.log("body:",body);
                response.writeHead(200,{'Content-Type':'text/html'});
                response.end('hellw world\n');
            })
        }).listen(8088);
        */


    </script>
</pre>